[Android] 非靜態內部類別可能造成記憶體洩漏


Posted by imcloudwu on 2021-09-13

常見用法

public class JavaTester {

    class MyHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    }
}

This Handler class should be static or leaks might occur (com.example.kotlintest.JavaTester.MyHandler)


非靜態內部類別(包含匿名類別)會保持對外部類別的強引用
若內部類別生命週期長於外部會造成記憶體洩漏

案例整理

Lambda 表達式如果未呼叫外部成員或方法,會被編譯成靜態

Kotlin Java
Capturing lambdas Leak Leak
Non-capturing lambdas No Leak No Leak
Inner class Leak Leak
Anonymous class Leak Leak

解決方向

  1. 確保內部生命週期短於外部
  2. 避免使用非靜態內部類別(包含匿名類別)
  3. 若一定需要呼叫到外部成員或方法,使用弱引用(WeakReference)將外部類別傳遞給內部

內部類別寫法

靜態

Java

public class OuterClass {
   public static class InnerClass {
   }
}

Kotlin

class OuterClass {
    class InnerClass {
    }
}

非靜態

Java

public class OuterClass {
   public class InnerClass {
   }
}

Kotlin

class OuterClass {
    inner class InnerClass {
    }
}

#memory leak #handler #inner class #Android #Kotlin #java







Related Posts

Day00 那些年我所不知道的 Web API 們

Day00 那些年我所不知道的 Web API 們

Caffe & GoogLeNet,怎麼幫助機器人更好地辨識物體

Caffe & GoogLeNet,怎麼幫助機器人更好地辨識物體

【Day02】The Shell(中)

【Day02】The Shell(中)


Comments